var coordInfo = null;
const letter = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'];
const letterIndex = {'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9}

// 计算坐标
function calculateCoordinate () {
    const windowWidth = $(window).width();
    const windowHeight = $(window).height();

    const scale = Math.min(windowWidth / boardWidth, windowHeight / boardHeight);

    // 棋盘外边距
    const actualBoardMarginX = ($("#chess-board").width() - boardWidth * scale) / 2;
    const actualBoardMarginY = ($("#chess-board").height() - boardHeight * scale) / 2;
    // 棋盘内边距
    const actualBoardPadding = boardPadding * scale;
    // 棋格宽度
    const actualUnitSize = unitSize * scale;

    coordInfo = {
        scale: scale,
        boardMarginX: actualBoardMarginX,
        boardMarginY: actualBoardMarginY,
        boardPadding: actualBoardPadding,
        unitSize: actualUnitSize
    }
}

// 棋子坐标
function pieceCoord (x, y, size=null) {
    if (size === null) {
        size = coordInfo.unitSize;
    }

    const pX = coordInfo.boardMarginX + coordInfo.boardPadding + x * coordInfo.unitSize - size / 2;
    const pY = coordInfo.boardMarginY + coordInfo.boardPadding + y * coordInfo.unitSize - size / 2;

    return {
        x: pX,
        y: pY
    }
}

// 放置棋子
function placePieces (piece){
    size = coordInfo.unitSize;
    zIndex = '0'
    if (piece.data('status') === 'up') {
        size = coordInfo.unitSize * 1.2;
        zIndex = '1'
    }

    const x = piece.data('x');
    const y = piece.data('y');

    const coord = pieceCoord(x, y, size);

     piece.css({
        'width': size,
        'height': size,
        'left': coord.x,
        'top': coord.y,
        'z-index': zIndex
    })
}

// 初始化布局
function initLayout(color) {
    userHolderColor = color;
    calculateCoordinate();
    for(let i = 0; i < pieceList.length; i++) {
        var y = pieceList[i][2];
        if (userHolderColor === "red") {
            y = 9 - y;
        }
        piece = $("#" + pieceList[i][0])
        piece.data({
            "x": pieceList[i][1],
            "y": y,
            "status": "down",
        })

        placePieces(piece);
    }
}

// 监听窗口大小变化
$(window).resize(function () {
    // 重新计算坐标
    calculateCoordinate();

    // 重新放置棋子
    $(".piece").each(function () {
        placePieces($(this));
    });

    // 重新放置选中框
    $(".allowed-move").each(function () {
        placeAllowedMove($(this));
    });

    // 重新放置选中框
    $(".un-move").each(function () {
        placeAllowedMove($(this));
    });
});

// 选中框
function placeAllowedMove (obj) {
    const x = obj.data('x');
    const y = obj.data('y');
    const coord = pieceCoord(x, y);

     obj.css({
        'width': coordInfo.unitSize,
        'height': coordInfo.unitSize,
        'left': coord.x,
        'top': coord.y
    })
}

// 放下棋子
function pieceDown (piece) {
    piece.data({
        'status': 'down'
    })
    placePieces(piece);
}

// 拿起棋子
function pieceUp (piece) {
    piece.data({
        'status': 'up'
    })
    placePieces(piece);
}

// 获取位置上的棋子
function getPiece (x, y) {
    const pieces = $(".piece");
    for (let i = 0; i < pieces.length; i++) {
        const piece = $(pieces[i]);
        if (piece.is(':hidden')) {
            continue;
        }
        const pieceX = piece.data('x');
        const pieceY = piece.data('y');
        if (pieceX === x && pieceY === y) {
            return piece;
        }
    }
    return null;
}

// 获取位置上的棋子
function getAllowMove (x, y) {
    const pieces = $(".allowed-move");
    for (let i = 0; i < pieces.length; i++) {
        const piece = $(pieces[i]);
        const pieceX = piece.data('x');
        const pieceY = piece.data('y');
        if (pieceX === x && pieceY === y) {
            return piece;
        }
    }
    return null;
}

// 将棋盘转换为二维数组
function boardToArray () {
    board = ''
    for (let y = 0; y <= 9; y++) {
        let row = []
        for (let x = 0; x <= 8; x++) {
            const piece = getPiece(x, y);
            if (piece === null) {
                row.push('[' + getYString(y) + getXString(x) + '-ee0]')
            } else {
                row.push('[' + getYString(y) + getXString(x) + '-' + piece.attr('id') + ']')
            }
        }
        board += row.join(' ') + '/n';
    }

    return board;
}

// 判断是否同一方的棋子
function isSameColor (piece1, piece2) {
    return piece1.data('color') === piece2.data('color');
}

// 获取可走位置
function getMovePositions (piece) {
    const name = piece.data('id')
    const x = piece.data('x');
    const y = piece.data('y');

    moveList = []

    if (name === 'rook') {
        // 向上走
        for (let i = y - 1; i >= 0; i--) {
            targetPiece = getPiece(x, i)
            if (targetPiece === null) {
                moveList.push([x, i])
            } else {
                if (!isSameColor(piece, targetPiece)) {
                    moveList.push([x, i])
                }
                break
            }
        }
        // 向下走
        for (let i = y + 1; i < 10; i++) {
            targetPiece = getPiece(x, i)
            if (targetPiece === null) {
                moveList.push([x, i])
            } else {
                if (!isSameColor(piece, targetPiece)) {
                    moveList.push([x, i])
                }
                break
            }
        }
        // 向左走
        for (let i = x - 1; i >= 0; i--) {
            targetPiece = getPiece(i, y)
            if (targetPiece === null) {
                moveList.push([i, y])
            } else {
                if (!isSameColor(piece, targetPiece)) {
                    moveList.push([i, y])
                }
                break
            }
        }
        // 向右走
        for (let i = x + 1; i < 9; i++) {
            targetPiece = getPiece(i, y)
            if (targetPiece === null) {
                moveList.push([i, y])
            } else {
                if (!isSameColor(piece, targetPiece)) {
                    moveList.push([i, y])
                }
                break
            }
        }
    } else if (name === 'knight') {
        // 检查四周是否有棋子
        top_piece = getPiece(x, y - 1)
        right_piece = getPiece(x + 1, y)
        bottom_piece = getPiece(x, y + 1)
        left_piece = getPiece(x - 1, y)

        // 上2 左1
        nX = x - 1
        nY = y - 2
        targetPiece = getPiece(nX, nY)
        if (top_piece === null && nX >= 0 && nY >= 0 && nX <= 8 && nY <= 9) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 上2 右1
        nX = x + 1
        nY = y - 2
        targetPiece = getPiece(nX, nY)
        if (top_piece === null && nX >= 0 && nY >= 0 && nX <= 8 && nY <= 9) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 上1 左2
        nX = x - 2
        nY = y - 1
        targetPiece = getPiece(nX, nY)
        if (left_piece === null && nX >= 0 && nY >= 0 && nX <= 8 && nY <= 9) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 上1 右2
        nX = x + 2
        nY = y - 1
        targetPiece = getPiece(nX, nY)
        if (right_piece === null && nX >= 0 && nY >= 0 && nX <= 8 && nY <= 9) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 下2 左1
        nX = x - 1
        nY = y + 2
        targetPiece = getPiece(nX, nY)
        if (bottom_piece === null && nX >= 0 && nY >= 0 && nX <= 8 && nY <= 9) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 下2 右1
        nX = x + 1
        nY = y + 2
        targetPiece = getPiece(nX, nY)
        if (bottom_piece === null && nX >= 0 && nY >= 0 && nX <= 8 && nY <= 9) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 下1 左2
        nX = x - 2
        nY = y + 1
        targetPiece = getPiece(nX, nY)
        if (left_piece === null && nX >= 0 && nY >= 0 && nX <= 8 && nY <= 9) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 下1 右2
        nX = x + 2
        nY = y + 1
        targetPiece = getPiece(nX, nY)
        if (right_piece === null && nX >= 0 && nY >= 0 && nX <= 8 && nY <= 9) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
    } else if (name === 'bishop') {
        // 检查四周是否有棋子
        top_left_piece = getPiece(x - 1, y - 1)
        top_right_piece = getPiece(x + 1, y - 1)
        bottom_left_piece = getPiece(x - 1, y + 1)
        bottom_right_piece = getPiece(x + 1, y + 1)

        minY = 0
        maxY = 4
        if (userHolderColor === turnToMove) {
            minY = 5
            maxY = 9
        }

        // 左上
        nX = x - 2
        nY = y - 2
        targetPiece = getPiece(nX, nY)
        if (top_left_piece === null && nX >= 0 && nY >= minY && nX <= 8 && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 右上
        nX = x + 2
        nY = y - 2
        targetPiece = getPiece(nX, nY)
        if (top_right_piece === null && nX >= 0 && nY >= minY && nX <= 8 && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 左下
        nX = x - 2
        nY = y + 2
        targetPiece = getPiece(nX, nY)
        if (bottom_left_piece === null && nX >= 0 && nY >= minY && nX <= 8 && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 右下
        nX = x + 2
        nY = y + 2
        targetPiece = getPiece(nX, nY)
        if (bottom_right_piece === null && nX >= 0 && nY >= minY && nX <= 8 && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
    } else if (name === 'advisor') {
        minX = 3
        maxX = 5
        minY = 0
        maxY = 2
        if (userHolderColor === turnToMove) {
            minY = 7
            maxY = 9
        }

        // 左上
        nX = x - 1
        nY = y - 1
        targetPiece = getPiece(nX, nY)
        if (nX >= minX && nY >= minY && nX <= maxX && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 右上
        nX = x + 1
        nY = y - 1
        targetPiece = getPiece(nX, nY)
        if (nX >= minX && nY >= minY && nX <= maxX && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 左下
        nX = x - 1
        nY = y + 1
        targetPiece = getPiece(nX, nY)
        if (nX >= minX && nY >= minY && nX <= maxX && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 右下
        nX = x + 1
        nY = y + 1
        targetPiece = getPiece(nX, nY)
        if (nX >= minX && nY >= minY && nX <= maxX && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
    } else if (name === 'king') {
        minX = 3
        maxX = 5
        minY = 0
        maxY = 2
        if (userHolderColor === turnToMove) {
            minY = 7
            maxY = 9
        }

        // 上
        nX = x
        nY = y - 1
        targetPiece = getPiece(nX, nY)
        if (nY >= minY && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 下
        nX = x
        nY = y + 1
        targetPiece = getPiece(nX, nY)
        if (nY >= minY && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 左
        nX = x - 1
        nY = y
        targetPiece = getPiece(nX, nY)
        if (nX >= minX && nX <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 右
        nX = x + 1
        nY = y
        targetPiece = getPiece(nX, nY)
        if (nX >= minX && nX <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
    } else if (name === 'cannon') {
        // 上
        flag = false
        for (let i = y - 1; i >= 0; i--) {
            targetPiece = getPiece(x, i)
            if (!flag && targetPiece === null) {
                moveList.push([x, i])
            } else if (!flag && targetPiece !== null) {
                flag = true
            } else if (flag && targetPiece !== null) {
                if (!isSameColor(piece, targetPiece)) {
                    moveList.push([x, i])
                }
                break
            }
        }
        // 下
        flag = false
        for (let i = y + 1; i <= 9; i++) {
            targetPiece = getPiece(x, i)
            if (!flag && targetPiece === null) {
                moveList.push([x, i])
            } else if (!flag && targetPiece !== null) {
                flag = true
            } else if (flag && targetPiece !== null) {
                if (!isSameColor(piece, targetPiece)) {
                    moveList.push([x, i])
                }
                break
            }
        }

        // 左
        flag = false
        for (let i = x - 1; i >= 0; i--) {
            targetPiece = getPiece(i, y)
            if (!flag && targetPiece === null) {
                moveList.push([i, y])
            } else if (!flag && targetPiece !== null) {
                flag = true
            } else if (flag && targetPiece !== null) {
                if (!isSameColor(piece, targetPiece)) {
                    moveList.push([i, y])
                }
                break
            }
        }
        // 右
        flag = false
        for (let i = x + 1; i <= 8; i++) {
            targetPiece = getPiece(i, y)
            if (!flag && targetPiece === null) {
                moveList.push([i, y])
            } else if (!flag && targetPiece !== null) {
                flag = true
            } else if (flag && targetPiece !== null) {
                if (!isSameColor(piece, targetPiece)) {
                    moveList.push([i, y])
                }
                break
            }
        }
    } else if (name === 'pawn') {
        if (turnToMove === userHolderColor) {
            // 上
            nX = x
            nY = y - 1
            targetPiece = getPiece(nX, nY)
            if (nY >= 0 && nY <= 9) {
                if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                    moveList.push([nX, nY])
                }
            }
        } else {
            // 下
            nX = x
            nY = y + 1
            targetPiece = getPiece(nX, nY)
            if (nY >= 0 && nY <= 9) {
                if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                    moveList.push([nX, nY])
                }
            }
        }

        minY = 0
        maxY = 4
        if (turnToMove !== userHolderColor) {
            minY = 5
            maxY = 9
        }

        // 左
        nX = x - 1
        nY = y
        targetPiece = getPiece(nX, nY)
        if (nX >= 0 && nX <= 8 && nY >= minY && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
        // 右
        nX = x + 1
        nY = y
        targetPiece = getPiece(nX, nY)
        if (nX >= 0 && nX <= 8 && nY >= minY && nY <= maxY) {
            if (targetPiece === null || (targetPiece !== null && !isSameColor(piece, targetPiece))) {
                moveList.push([nX, nY])
            }
        }
    }
    return moveList;
}

// 显示可走位置
function showMovePositions(targetPositions) {
    for (let i = 0; i < targetPositions.length; i++) {
        const coord = pieceCoord(targetPositions[i][0], targetPositions[i][1]);
        const x = coord['x']
        const y = coord['y']

        var allowedMove = $("<div></div>");
        allowedMove.addClass("allowed-move");
        allowedMove.data({
            'x': targetPositions[i][0],
            'y': targetPositions[i][1]
        });
        allowedMove.appendTo("#chess-board");
        placeAllowedMove(allowedMove);
    }
}

function moveRecordPush(piece, nX, nY) {
    const data = {
        'color': piece.data('color'),
        'role': userHolderColor == piece.data('color') ? 'user': 'ai',
        'piece': piece.attr('id'),
        'from': {
            'x': piece.data('x'),
            'y': piece.data('y'),
            'string': getYString(piece.data('y')) + getXString(piece.data('x'))
        },
        'to': {
            'x': nX,
            'y': nY,
            'string': getYString(nY) + getXString(nX)
        },
        'eat': null,
        'string': convertChessMove(piece, nX, nY)
    }

    moveRecord.push(data);

    return data;
}

// 悔棋
function undoMoveRecord() {
    if (moveRecord.length > 0) {
        for (let i = 0; i < 2; i++) {
            let lastMove = moveRecord.pop();
            if (lastMove === undefined) {
                break;
            }
            pieceMove($('#' + lastMove.piece), lastMove.from.x, lastMove.from.y);
            if (lastMove.eat) {
                $('#' + lastMove.eat).show();
            }
        }
        $('.un-move').remove();
        if (moveRecord.length > 0) {
            const lastMove = moveRecord[moveRecord.length - 1];
            const unMovePiece = $("<div></div>");
            unMovePiece.addClass("un-move");
            unMovePiece.data({
                'x': lastMove.from.x,
                'y': lastMove.from.y,
            });
            unMovePiece.appendTo("#chess-board");
            placeAllowedMove(unMovePiece);
        }
    }
}

// 走棋
function pieceMove(piece, nX, nY) {
    // 取消所有可走位置
    $(".allowed-move").remove();

    const coord = pieceCoord(nX, nY);

    oX = piece.data('x');
    oY = piece.data('y');

    piece.data({
        "x": nX,
        "y": nY,
        "status": "down"
    });

    // 移除被吃子
    $(".piece").each(function () {
        if ($(this).data('x') === nX && $(this).data('y') === nY && !isSameColor(piece, $(this))) {
            $(this).hide();
            moveRecord[moveRecord.length - 1].eat = $(this).attr('id');
        }
    });

    // 移动棋子带动画
    piece.animate({
        "left": coord['x'],
        "top": coord['y'],
        "width": coordInfo.unitSize,
        "height": coordInfo.unitSize
    }, 200);

    // 标识
    $('.un-move').remove();
    const unMovePiece = $("<div></div>");
    unMovePiece.addClass("un-move");
    unMovePiece.data({
        'x': oX,
        'y': oY
    });
    unMovePiece.appendTo("#chess-board");
    placeAllowedMove(unMovePiece);
}

function getYString(y) {
    return letter[y];
}

function getXString(x) {
    return  (x + 1).toString();
}

// 转换象棋走棋术语
function convertChessMove(piece, toX, toY) {
    // 棋子类型和颜色
    const type = piece.data('id');
    const fromX = piece.data('x');
    const fromY = piece.data('y');
    const color = piece.data('color');
    const pieceName = piece.data('name')

    let string = '';
    const colorString = color === 'red' ? '红' : '黑';
    string += colorString + pieceName + '(' + piece.attr('id') + ')从';
    string += getYString(fromY) + getXString(fromX) + '走到';
    string += getYString(toY) + getXString(toX);

    return string;
}